package models

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
	"time"
)

var 坐标 struct {
	X0 int32
	Y0 int32
	X1 int32
	Y1 int32
}

func (rt *RunTime) 执行脚本(脚本 string, npcid int32) bool {
	脚本S := strings.Split(脚本, "\n")
	for _, 脚本行 := range 脚本S {
		if len(脚本行) == 0 {
			continue
		}
		脚本行len := len(脚本行)
		if 脚本行[脚本行len-1] == '\r' {
			脚本行 = 脚本行[:脚本行len-1]
		}
		分割 := strings.Split(脚本行, " ")
		switch 分割[0] {
		case "/城主":
			if rt.V角色内容.V区域 != nil {
				rt.V角色内容.V区域.V管理人 = rt.V角色.Id
				db.Table(rt.V角色内容.V区域).Where("id=?", rt.V角色内容.V区域.Id).Update(map[string]interface{}{"V管理人": rt.V角色.Id})
				m_电信服务 <- &电信{
					来源:   nil,
					类型:   E系统消息,
					通讯内容: rt.V角色内容.V区域.V区域名称 + "的管理人已经改为:" + rt.V角色.V名字,
				}
			}
		case "/造物":
			if len(分割) != 3 {
				rt.消息_系统消息(3, "造物格式不正确")
				return false
			}
			数量 := int64(0)
			if t, err := strconv.ParseInt(分割[2], 10, 64); err != nil {
				rt.消息_系统消息(3, "造物失败:数量不正确")
				return false
			} else {
				数量 = t
			}
			switch 分割[1] {
			case "金币":
				rt.V角色.V金币 += 数量
				rt.消息_系统消息(3, "获得金币:"+分割[2])
			default:
				复制物品, err := 物品_获取系统物品列表_中文(分割[1])
				if err != nil {
					rt.消息_系统消息(3, "造物失败:无此物品")
					return false
				}
				物品信息 := 物品_获取物品信息(复制物品.V信息ID)
				if 物品信息.V数量 == true {
					新物品 := 创建物品(复制物品.Id)
					if 新物品.V数量 != 0 {
						新物品.V数量 = uint16(数量)
					}
					rt.背包_放置物品(新物品)
				} else {
					for i := int64(0); i < 数量; i++ {
						新物品 := 创建物品(复制物品.Id)
						rt.背包_放置物品(新物品)
					}
				}

			}
		case "/回城":
			x, y := F位置_游戏位置转UE4位置(rt.V角色.V出生x, rt.V角色.V出生y)
			rt.Func位置移动(x, y, 0)
		case "/召唤":
			if len(分割) != 6 {
				///召唤 蜂王 10 10 10
				rt.消息_系统消息(3, "召唤失败:正确指令为: /召唤 怪物中文名称 数量 生成范围 活动范围 是否保存")
				return false
			}
			数量 := uint8(0)
			if t, err := strconv.Atoi(分割[2]); err != nil {
				rt.消息_系统消息(3, "召唤失败:数量不正确")
				return false
			} else {
				数量 = uint8(t)
			}
			生成范围 := uint8(0)
			if t, err := strconv.Atoi(分割[3]); err != nil {
				rt.消息_系统消息(3, "召唤失败:生成范围不正确")
				return false
			} else {
				生成范围 = uint8(t)
			}
			活动范围 := uint8(0)
			if t, err := strconv.Atoi(分割[4]); err != nil {
				rt.消息_系统消息(3, "召唤失败:活动范围不正确")
				return false
			} else {
				活动范围 = uint8(t)
			}
			保存到数据库 := false
			if t, err := strconv.ParseBool(分割[5]); err != nil {
				rt.消息_系统消息(3, "召唤失败:没有提供是否保存到数据库参数")
				return false
			} else {
				保存到数据库 = t
			}
			if err := func() error {
				怪物, ok := m_怪物信息[分割[1]]
				if ok == false {
					return errors.New("召唤失败:不存在的怪物:" + 分割[1])
				}
				生成 := &Struct怪物生成表{}
				生成.V坐标 = make(map[int32]int32)
				坐标X, 坐标Y := F位置_UE4位置转游戏位置(rt.V角色内容.X, rt.V角色内容.Y)
				生成.V坐标[坐标X] = 坐标Y
				生成.V怪物中文名称 = 怪物.V中文名称
				生成.IsUse = true
				生成.V数量 = 数量
				生成.V活动范围 = 活动范围
				生成.V生成范围 = 生成范围
				生成.V智力 = 3
				if 保存到数据库 == true {
					if _, err := db.Insert(生成); err != nil {
						return errors.New("召唤失败:" + err.Error())
					}
				}
				m_怪物生成表[生成.Id] = 生成 //添加到生成表里，这样就不用重启了
				rt.V角色内容.V空间.召唤怪物(生成)
				return nil
			}(); err != nil {
				rt.消息_系统消息(3, err.Error())
			}
			/*if err := GM_召唤(rt.V角色内容.V空间, 分割[1], 数量, 生成范围, 活动范围, rt.V角色内容.X, rt.V角色内容.Y, 保存到数据库); err != nil {

			}*/
			return true
		case "/效果":
			if len(分割) != 2 {
				rt.消息_系统消息(3, "脚本内容错，应该为/效果 效果名称")
				return false
			}
			rt.动作_效果(分割[1], 0, 0)
		case "/加血", "/加蓝":
			if len(分割) != 4 {
				rt.消息_系统消息(3, "脚本内容错，应该为/加血 外观 加多少 多少秒")
				return false
			}
			var 加多少, 多少秒 int
			if t, err := strconv.Atoi(分割[2]); err != nil {
				rt.消息_系统消息(3, "加多少正确")
				return false
			} else {
				加多少 = t
			}
			if t, err := strconv.Atoi(分割[3]); err != nil {
				rt.消息_系统消息(3, "多少秒不正确")
				return false
			} else {
				多少秒 = t
			}
			rt.动作_效果(分割[1], 0, 0)
			go func() {
				for i := 0; i < 多少秒; i++ {
					if 分割[0] == "/加血" {
						F地图_发送信息(rt.V角色内容, &S交换数据{
							V类型:  E交换数据类型_修改基础属性,
							V发送人: rt.V角色内容,
							V内容: map[uint16]float32{
								E基础属性_当前血量: float32(加多少),
							},
						})
					} else if 分割[0] == "/加蓝" {
						F地图_发送信息(rt.V角色内容, &S交换数据{
							V类型:  E交换数据类型_修改基础属性,
							V发送人: rt.V角色内容,
							V内容: map[uint16]float32{
								E基础属性_当前蓝量: float32(加多少),
							},
						})
					}
					time.Sleep(time.Second)
				}
			}()
		case "/技能":
			if len(分割) != 3 {
				rt.消息_系统消息(3, "脚本内容错，应该为 /技能 技能中文名 等级")
				return false
			}
			技能信息, err := 技能_获取技能信息_中文(分割[1])
			if err != nil {
				rt.消息_系统消息(3, "技能不存在!")
				return false
			}
			var 等级 int
			if t, err := strconv.Atoi(分割[2]); err != nil {
				rt.消息_系统消息(3, "等级不正确")
				return false
			} else {
				等级 = t
			}
			F地图_发送信息(rt.V角色内容, &S交换数据{
				V类型:  E交换数据类型_修改辅助技能,
				V发送人: rt.V角色内容,
				V内容: S额外属性{
					V到期时间:  time.Now().Add(time.Duration(技能信息.V辅助时长[等级]) * time.Second),
					V唯一ID:  技能信息.V辅助ID,
					V技能英文名: 技能信息.V技能英文名,
					V添加内容:  技能信息.V基础属性[等级]},
			})
		case "/移动":
			if len(分割) < 3 {
				rt.消息_系统消息(3, "脚本内容错，应该为 X Y Z")
				return false
			}
			var x, y, z int32
			if t, err := strconv.Atoi(分割[1]); err != nil {
				rt.消息_系统消息(3, "X位置不正确")
				return false
			} else {
				x = int32(t)
			}
			if t, err := strconv.Atoi(分割[2]); err != nil {
				rt.消息_系统消息(3, "X位置不正确")
				return false
			} else {
				y = int32(t)
			}
			if len(分割) == 4 {
				if t, err := strconv.Atoi(分割[3]); err != nil {
					rt.消息_系统消息(3, "X位置不正确")
					return false
				} else {
					z = int32(t)
				}
			}
			//检查当前角色条件是否满足指定位置的条件
			位置定义 := 位置_获取位置(x, y)
			if (位置定义.V等级下限 != 0 && rt.V角色.V等级 < 位置定义.V等级下限) || (位置定义.V等级上限 != 0 && rt.V角色.V等级 > 位置定义.V等级上限) {
				rt.消息_系统消息(3, fmt.Sprintf("您的等级无法传送到此区域,此区域等级要求%d~%d", 位置定义.V等级下限, 位置定义.V等级上限))
				return false
			}
			x, y = F位置_游戏位置转UE4位置(x, y)
			rt.Func位置移动(x, y, z)
		case "/地图":
			if len(分割) != 3 {
				rt.消息_系统消息(3, "放置失败:正确指令为: /地图 地图名称 空间编号")
				return false
			}
		case "/放置NPC":
			if len(分割) != 3 {
				rt.消息_系统消息(3, "放置失败:正确指令为: /放置NPC NPC名称 参考NPC中文名称")
				return false
			}
			参考NPC, ok := m_Npc列表[分割[2]]
			if ok == false {
				rt.消息_系统消息(3, "放置失败:参考NPC错误")
				return false
			}
			npc := &SNpc列表{}
			npc.V中文名称 = 分割[1]
			npc.V英文名称 = 参考NPC.V英文名称
			npc.X, npc.Y = F位置_UE4位置转游戏位置(rt.V角色内容.X, rt.V角色内容.Y)
			npc.Z = rt.V角色内容.Z + 200
			npc.V方向 = rt.V角色内容.V方向
			npc.V欢迎语 = 参考NPC.V欢迎语

			if _, err := db.Insert(npc); err != nil {
				rt.消息_系统消息(3, "放置失败:"+err.Error())
				return false
			}
			rt.V角色内容.V空间.F添加内容(E类别_NPC, rt.V角色内容.X, rt.V角色内容.Y, npc.Z, npc.V方向, npc)
			新NPC菜单 := NPC_获取菜单(参考NPC.Id, 0, 0, true)
			for _, v := range 新NPC菜单 {
				var 菜单 StructNPC菜单
				菜单 = *v
				菜单.Id = 0 //设置为添加
				菜单.NpcID = npc.Id
				if _, err := db.Insert(菜单); err != nil {
					rt.消息_系统消息(3, "放置时,添加菜单失败:"+err.Error())
					return true
				}
			}
			//m_NPC菜单[npc.Id] = 新NPC菜单 //因为两个一样,所以这样做也可以
			return true
		case "/回城点":
			rt.V角色.V出生x, rt.V角色.V出生y = F位置_UE4位置转游戏位置(rt.V角色内容.X, rt.V角色内容.Y)
			rt.消息_系统消息(3, "回城点已设置")
		case "/学习技能": //学习新的技能  /学习技能 等级
			等级 := uint16(99)
			if len(分割) == 3 {
				if t, err := strconv.ParseUint(分割[2], 10, 16); err != nil {
					rt.消息_系统消息(3, "系统配置错,学习技能第二个选项必须为数字")
				} else {
					等级 = uint16(t)
				}
			}
			if err := rt.技能_等级增加(分割[1], 等级); err != nil {
				rt.消息_系统消息(3, "出错:"+err.Error())
				return false
			} else {
				rt.消息_系统消息(3, "已学习技能:"+分割[1])
			}
		case "/副本":
			if len(分割) != 4 {
				rt.消息_系统消息(3, "格式错")
				return false
			}
			var x, y int32
			if t, err := strconv.Atoi(分割[2]); err != nil {
				rt.消息_系统消息(3, "格式错:X")
				return false
			} else {
				x = int32(t)
			}
			if t, err := strconv.Atoi(分割[3]); err != nil {
				rt.消息_系统消息(3, "格式错:Y")
				return false
			} else {
				y = int32(t)
			}

			副本, err := 创建空间(分割[1])
			if err != nil {
				rt.消息_系统消息(3, "无法创建副本:"+err.Error())
				return false
			}
			x, y = F位置_游戏位置转UE4位置(x, y)
			副本.F添加内容(E类别_人物, x, y, 0, 0, rt.V角色内容)
			rt.Func位置移动(x, y, 0)
			rt.消息_系统消息(3, "您已进入副本:"+分割[1])
		case "/升级":
			if t, err := strconv.Atoi(分割[1]); err != nil {
				rt.消息_系统消息(3, "提示的等级不正确")
				return false
			} else {
				for i := 0; i < t; i++ {
					rt.角色升级()
				}
			}
		case "/个人仓库", "/公会仓库":
			if len(分割) != 2 {
				rt.消息_系统消息(3, "格式不正确")
			}
			状态 := &S状态_仓库{}
			session := db.NewSession()
			//var domain string
			if 分割[0] == "/个人仓库" {
				session = session.Where("类型=4").Where("uid=?", rt.V角色.Id)
				状态.个人仓库 = true
			} else {
				状态.个人仓库 = false
				if (len(rt.V角色.V行会名) == 0) || (strings.Index(rt.V角色.V行会名, "+") != -1) {
					rt.消息_系统消息(3, "您未加入行会")
					return false
				}
				session = session.Where("类型=5").Where("行会名=?", rt.V角色.V行会名)
			}
			状态.主类 = 分割[1]
			//domain += fmt.Sprintf("&[V主类,=,'%s']", 分割[1])
			var bblb []*S背包列表
			if err := session.Where("主类=?", 分割[1]).OrderBy("time asc").Find(&bblb); err != nil {
				panic(err)
			}
			tx := CreateBuff(50)
			tx.AddInt16(0x00E9)
			tx.AddInt32(npcid)
			tx.AddStringAndLen(分割[1])
			tx.AddInt32(0x00002710)
			tx.AddInt32(0x00001388)
			tx.AddInt32(0x000001F4)
			tx.AddInt32(0x0008462B)
			tx.AddInt32(0x01)
			tx.AddInt32(int32(len(bblb)))
			for _, 背包 := range bblb {
				tx.AddStringAndLen(背包.Name)
				tx.AddInt32(背包.Id)
			}
			tx.AddInt32(0x00)
			rt.AddHeadSend10(0x0A, [][]byte{{}, tx.Buff})
			rt.V角色.V状态 = E角色状态_仓库
			rt.V角色.V状态内容 = 状态
		case "/创建行会":
			if len(分割) != 2 {
				rt.消息_系统消息(3, "格式不正确")
			}
			if 分割[1] == "" {
				rt.消息_系统消息(3, "行会名称不能为空")
				return false
			}
			if rt.V角色.V行会名 != "" {
				rt.消息_系统消息(3, "已有行会是无法申请创建行会的")
				return false
			}
			//在这里检测行会名称是否规范
			if strings.Index(分割[1], "+") != -1 {
				rt.消息_系统消息(3, "行会名称不合法")
				return false
			}
			rt.V角色.V行会名 = 分割[1]
			rt.V角色.V会长 = true
			rt.消息_系统消息(3, "您已创建行会:"+分割[1]+",目前您重新登录后才会显示。")
		case "/删除行会":

		case "/改名":
		case "/改发型":
		case "/改发色":
		case "/技能经验":
			if len(分割) != 3 {
				rt.消息_系统消息(3, "格式不正确 /技能经验 技能名称 经验值")
				return false
			}
			if t, err := strconv.Atoi(分割[2]); err != nil {
				rt.消息_系统消息(3, "经验值不正确")
				return false
			} else {
				技能信息, err := 技能_获取技能信息_中文(分割[1])
				if err != nil {
					rt.消息_系统消息(3, "没有发现的技能名称:"+分割[1])
					return false
				}
				if 技能信息.V攻击类型 > 2 {
					rt.消息_系统消息(3, "技能卷只能用于普通技能")
					return false
				}
				技能, ok := rt.V技能列表[技能信息.Id]
				if ok == false {
					rt.消息_系统消息(3, "此技能还没有学会")
					return false
				}
				rt.技能_增加经验(技能信息, 技能, int64(t))
			}
		case "/增加经验":
			if t, err := strconv.Atoi(分割[1]); err != nil {
				rt.消息_系统消息(3, "提示的等级不正确")
				return false
			} else {
				rt.V角色.V当前经验 += int64(t)
				i := 0
				for ; i < 1000; i++ { //限制1000次内一定会退出
					if 总经验, ok := m_等级经验[rt.V角色.V等级]; ok == true {
						if rt.V角色.V当前经验 >= 总经验 {
							rt.V角色.V当前经验 -= 总经验
							rt.角色升级()
							continue
						}
					}
					break
				}
				if i >= 1000 {
					fmt.Println("循环超过次数:位置3")
				}
			}
		case "/任务":
			if len(分割) != 3 {
				rt.消息_系统消息(3, "格式不正确： /任务 任务ID 标志")
				continue
			}
			任务ID := int16(0)
			if t, err := strconv.Atoi(分割[1]); err != nil {
				rt.消息_系统消息(3, "任务ID不正确")
				return false
			} else {
				任务ID = int16(t) //开始新任务
			}
			标志 := int32(0)
			if t, err := strconv.Atoi(分割[2]); err != nil {
				rt.消息_系统消息(3, "任务标志不正确")
				return false
			} else {
				标志 = int32(t) //开始新任务
			}
			switch 标志 {
			case -1: //删除任务
				delete(rt.V角色.V任务状态, 任务ID)
			case -2:
				标志 = int32(time.Now().Unix())
			}
			rt.V角色.V任务状态[任务ID] = 标志
		case "/变身":
			var 名称 string
			时长 := float32(3600)
			n := len(分割)
			if n == 1 {
				名称 = "super"
			}
			if n > 1 {
				名称 = 分割[1]
			}
			if n > 2 {
				if t, err := strconv.Atoi(分割[2]); err != nil {
					rt.消息_系统消息(3, "时间不正确")
					return false
				} else {
					时长 = float32(t) //开始新任务
				}
			}
			if 名称 == "super" {
				rt.动作_变身(true)
				rt.V角色内容.V变身怪物 = ""
			} else {
				变身, ok := m_怪物信息[分割[1]]
				if ok == false {
					rt.消息_系统消息(3, "不存在的变身名称")
					return false
				}
				rt.V角色内容.V变身怪物 = 变身.V英文名称
				动作_内容加辅助技能(rt.V角色内容, "NULL_ENCHANT", 时长)
			}

		case "/转生":
			var 角色最高等级 uint16
			if t, err := strconv.Atoi(GetConfig("转生", "角色最高等级", "300")); err != nil {
				角色最高等级 = 300
			} else {
				角色最高等级 = uint16(t)
			}
			if rt.V角色.V等级 < 角色最高等级 {
				rt.消息_系统消息(3, fmt.Sprintf("开玩笑，你必须等到:%d才能来找我", 角色最高等级))
				return false
			}
			//初始化rt变量

			for _, v := range rt.V技能列表 {
				技能信息, err := 技能_获取技能信息(v.V技能ID)
				if err != nil {
					panic("无效的技能信息ID:" + strconv.Itoa(int(v.V技能ID)))
				}
				db.Where("id=?", v.Id).Delete(v)
				实时技能, _ := rt.技能_获取实时技能列表(技能信息.V技能英文名)
				rt.技能_设置技能等级(技能信息, 实时技能, false)

			}
			角色 := rt.V角色
			rt.V技能列表 = make(map[int32]*Struct技能列表)
			属性, ok := m_新角色属性[rt.V角色.V职业]
			if ok == false {
				panic("未发现的新角色职业属性:" + 角色.V职业)
			}
			角色.V力量 = 0
			角色.V敏捷 = 0
			角色.V精神 = 0
			角色.V红魔法 = 0
			角色.V黄魔法 = 0
			角色.V蓝魔法 = 0
			角色.V白魔法 = 0
			角色.V黑魔法 = 0
			角色.V转生++
			角色.V等级 = 1
			转生点数, _ := strconv.Atoi(GetConfig("转生", "转生点数", "10"))
			角色.V可分配点数 = 属性.V可分配点数 + uint16(转生点数)
			角色.X = 属性.V出生x
			角色.Y = 属性.V出生y
			角色.Z = 0
			角色.V出生x = 属性.V出生x
			角色.V出生y = 属性.V出生y
			角色.V移动速度 = 1
			角色.V当前经验 = 0
			rt.Func角色加点(属性.V力量, 属性.V敏捷, 属性.V精神, 属性.V白魔法, 属性.V红魔法, 属性.V蓝魔法, 属性.V黄魔法, 属性.V黑魔法)
			x, y := F位置_游戏位置转UE4位置(角色.V出生x, 角色.V出生y)
			rt.技能_设置技能_英文(0, "")
			rt.技能_设置技能_英文(1, "")
			rt.技能_设置技能_英文(2, "")
			rt.Func位置移动(x, y, 0)
			rt.消息_系统消息(3, fmt.Sprintf("恭喜您完成转生."))
			rt.发送用户信息(用户信息_行会)
			return true
		case "/重载基本数据", "/reload":
			重载基本数据()
			rt.消息_系统消息(3, fmt.Sprintf("重载数据已完成"))
		case "/材料合成":
			tx := CreateBuff(30)
			tx.AddBytes(String2Byte("0A 01 11 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 08 00 00 00 0A 00 00 00 0B 00 00 00 0F 00 00 00 10 00 00 00 11 00 00 00 12 00 00 00 13 00 00 00 14 00 00 00 1A 00 00 00 24 00 00 00"))
			rt.AddHeadSend10(0x0A, [][]byte{{}, tx.Buff})
		case "/坐标范围":
			rt.消息_系统消息(3, fmt.Sprintf("X0:%d,Y0:%d,X1:%d,Y1:%d", 坐标.X0, 坐标.Y0, 坐标.X1, 坐标.Y1))
		case "/清除坐标范围":
			坐标.X0 = 65535
			坐标.Y0 = 65535
			坐标.X1 = 0
			坐标.Y1 = 0
			rt.消息_系统消息(3, fmt.Sprintf("坐标已准备好"))
		case "/经验倍率", "/砸宝倍率", "/掉宝倍率":
			if len(分割) != 2 {
				rt.消息_系统消息(3, "格式不正确")
				return false
			}
			S倍率 := 分割[1]
			if S倍率 == "0" {
				S倍率 = GetConfig("系统", 分割[0][1:], "1")
			}
			倍率, err := strconv.ParseFloat(S倍率, 32)
			if err != nil {
				rt.消息_系统消息(3, "格式不正确")
				return false
			}
			switch 分割[0] {
			case "/经验倍率":
				m_历史长河.V经验倍率 = float32(倍率)
			case "/砸宝倍率":
				m_历史长河.V砸宝倍率 = float32(倍率)
			case "/掉宝倍率":
				m_历史长河.V掉宝倍率 = float32(倍率)
			}
			rt.消息_系统消息(3, fmt.Sprintf("%s:[%f] 设置已完成", 分割[0][1:], m_历史长河.V经验倍率))
		case "/献祭":
			//攻击力10倍，生命10倍，防御10倍，限时5分钟
			break
		case "/历史长河":
			rt.消息_系统消息(3, m_历史长河.V说明)
		case "/召唤宠物ID":
			if len(分割) != 2 {
				rt.消息_系统消息(3, "格式不正确")
				return false
			}
			if t, err := strconv.Atoi(分割[1]); err != nil {
				rt.消息_系统消息(3, "宠物ID不正确")
				return false
			} else {
				if err := rt.召唤宠物(int32(t)); err != nil {
					rt.消息_系统消息(3, "宠物召唤不成功:"+err.Error())
					return false
				}
				rt.消息_系统消息(3, "宠物召唤完成:")
			}
		case "/召唤宠物":
			if len(分割) != 2 {
				rt.消息_系统消息(3, "格式不正确")
				return false
			}
			找到 := false
			for _, v := range m_宠物列表 {
				if v.V宠物名称 == 分割[1] {
					return rt.执行脚本(fmt.Sprintf("/召唤宠物ID %d", v.Id), npcid)
				}
			}
			if 找到 == false {
				rt.消息_系统消息(3, "不存在的宠物")
				return false
			}
		default:
			rt.消息_系统消息(3, "未知脚本类型:"+分割[0])
			return false
		}
	}
	return true
}

//功能 检查背包里是否有指定的物品,做任务,菜单时使用
func (rt *RunTime) 脚本_查询条件(物品或要求名称 string, 数量 float32) error {
	switch 物品或要求名称 {
	case "金币":
		if rt.V角色.V金币 > int64(数量) {
			return nil
		}
	case "要求等级下限":
		if rt.V角色.V等级 < uint16(数量) {
			return errors.New(fmt.Sprintf("等级不能小于%d", int(数量)))
		}
	case "要求等级上限":
		if rt.V角色.V等级 > uint16(数量) {
			return errors.New(fmt.Sprintf("等级不能大于%d", int(数量)))
		}
	}
	for 背包ID := uint8(0); 背包ID < 4; 背包ID++ {
		背包 := rt.背包_获取背包(背包ID)
		if 背包.Time.Sub(time.Now()) < 0 {
			continue
		}
		for x := 0; x < 9; x++ {
			for y := 0; y < 13; y++ {
				物品ID := 背包.Buff[x][y]
				if 物品ID <= 0 {
					continue
				}
				物品 := rt.V物品列表[物品ID]
				if 物品.V中文名称 != 物品或要求名称 {
					continue
				}
				物品信息 := 物品_获取物品信息(物品.V信息ID)
				if 物品信息.V数量 == false {
					数量--
				} else {
					数量 -= float32(物品.V数量)
				}
				if 数量 <= 0 {
					return nil
				}
			}
		}
	}
	return errors.New(fmt.Sprintf("物品[%s]的数量不够%d个", 物品或要求名称, int(数量)))
}
func (rt *RunTime) 脚本_执行条件(物品名称 string, 数量 float32) bool {
	原始数量 := 数量
	switch 物品名称 {
	case "金币":
		rt.V角色.V金币 -= int64(数量)
		rt.发送用户信息(用户信息_金币)
		rt.消息_系统消息(3, fmt.Sprintf("您已成功消费%d金币", int(数量)))
		return true
	case "要求等级下限":
		return true
	case "要求等级上限":
		return true
	}
	for 背包ID := uint8(0); 背包ID < 4; 背包ID++ {
		背包 := rt.背包_获取背包(背包ID)
		if 背包.Time.Sub(time.Now()) < 0 {
			continue
		}
		for x := uint8(0); x < 9; x++ {
			for y := uint8(0); y < 13; y++ {
				物品ID := 背包.Buff[x][y]
				if 物品ID <= 0 {
					continue
				}
				物品 := rt.V物品列表[物品ID]
				if 物品.V中文名称 != 物品名称 {
					continue
				}
				物品信息 := 物品_获取物品信息(物品.V信息ID)
				if 物品信息.V数量 == false {
					物品, err := rt.背包_取出指定位置物品(背包, x, y, 0)
					if err != nil {
						panic("~~~~~")
					}
					db.Where("id=?", 物品.Id).Delete(物品)
					rt.同步_背包指定点(背包, x, y, false)
					数量--
				} else {
					if 数量 >= float32(物品.V数量) { //如果需要的数量大于当前当前物品的数量，那么物品就会消失了
						数量 -= float32(物品.V数量)
						rt.背包_取出指定位置物品(背包, x, y, 0)
						db.Where("id=?", 物品.Id).Delete(物品)
						rt.同步_背包指定点(背包, x, y, false)
					} else { //如果需要的数量小于物品的数量，则物品会保留下来
						rt.背包_取出指定位置物品(背包, x, y, uint16(数量))
						数量 = 0
						rt.同步_背包指定点(背包, x, y, true)
					}
				}
				if 数量 <= 0 {
					rt.消息_系统消息(3, fmt.Sprintf("已消耗物品[%s]%d个", 物品名称, int(原始数量)))
					return true
				}
			}
		}
	}
	panic("确认可用了,为什么还会到这里")
}
